package bloque;

import java.io.FileNotFoundException;
import java.io.IOException;
import bloque.*;

public class Arbol {
	public static final int sizeNodo = 128;
	/**
	 * La altura del arbol. Si es 0 significa que el arbol solo tiene un nodo
	 * hoja, que es la raiz.
	 */
	private int altura;
	private ArchivoBloques archArbol;
	private Bloque NodoActual = null;
	
	public Arbol() throws FileNotFoundException, IOException {
            
        this.archArbol = new ArchivoBloques("ArchivoArbol.dat",sizeNodo);
        if (this.archArbol.GetCantidadBloques() <= 1) {
        	HojaArbol NodoRaizHoja = new HojaArbol();
        	this.NodoActual = new Bloque(sizeNodo);
        	NodoActual.agregarRegistroABloque(NodoRaizHoja.convertirNodoABytes());
        	archArbol.EscribirBloque(NodoActual.convertirBloqueABytes(), 0);
			this.altura = 0;
		} else {
			byte [] bytesBloqueTemporal = new byte[sizeNodo];
			NodoArbol nodoRaiz= new NodoArbol();
			archArbol.LeerBloque(bytesBloqueTemporal, 0);
			bytesBloqueTemporal = this.NodoActual.convertirBloqueABytes();
			nodoRaiz.convertirBytesANodo(bytesBloqueTemporal);
			this.altura = nodoRaiz.getNivel();
		}
                  
    }
	public void insertar(String palabra, int offset, float tamanioGlobal) throws ArbolBSharpException {
		
		if (this.NodoActual == null)
			throw new ArbolBSharpException("No esta abierto el arbol");
			
		if (altura == 0) {
			insertarEnRaizHoja(palabra, offset, tamanioGlobal);
		} else {
				}
		}
	
	
	private void insertarEnRaizHoja(String palabra, int offset, float tamanioGlobal) throws ArbolBSharpException {
		try {
			HojaArbol hojaRaiz = new HojaArbol();
			this.NodoActual.rwBloque();
			hojaRaiz.convertirBytesANodo(this.NodoActual.getProximoRegistro());
			hojaRaiz.insertar(palabra, offset, tamanioGlobal);
			if (this.NodoActual.agregarRegistroABloque(hojaRaiz.convertirNodoABytes()) < 0) {
				// OVERFLOW
				HojaArbol nodoDerecha;
				HojaArbol nodoIzquierda;
				NodoArbol nuevaRaiz;

				nodoIzquierda = hojaRaiz;		
				nodoDerecha = new HojaArbol();
				//nodoDerecha.setPosicionEnArchivo(buffer.getBloqueLibre());			
				int idDer = (int) archArbol.GetCantidadBloques();
				nuevaRaiz = new NodoArbol();
				//nuevaRaiz.setPosicionEnArchivo(0);
				int idRaiz = 0;
				nuevaRaiz.setNivel(1);
				HojaArbol hojaAux = new HojaArbol();
				nodoIzquierda.dividirHoja(nodoDerecha, hojaAux);
				nodoIzquierda =  hojaAux;
				Bloque bloqueD = new Bloque(sizeNodo);
				
	        	bloqueD.agregarRegistroABloque(nodoDerecha.convertirNodoABytes());
				// Guardar el nodo Derecha
	        	archArbol.EscribirBloque(bloqueD.convertirBloqueABytes(), idDer);
				nodoIzquierda.setPunteroASiguiente(idDer);
				int idIzq = (int) archArbol.GetCantidadBloques();
				this.NodoActual.actualizarRegistro(0, nodoIzquierda.convertirNodoABytes());
				// Guardar el nodo Izq
				archArbol.EscribirBloque(this.NodoActual.convertirBloqueABytes(),idIzq);	
				
				//Modifico la nueva raiz q ahora es nodo, le agrego las claves y los punteros a hijos
				nuevaRaiz.agregarPrimero(nodoDerecha.getPalabra(nodoDerecha.getMayorRegistro()), idDer);
				nuevaRaiz.agregarPrimero(nodoIzquierda.getPalabra(nodoIzquierda.getMayorRegistro()), this.NodoActual.getIdBloque());
				
				//Escribo la Raiz
				Bloque bloqueRaiz = new Bloque(sizeNodo);
				bloqueRaiz.agregarRegistroABloque(nuevaRaiz.convertirNodoABytes());
				archArbol.EscribirBloque(bloqueRaiz.convertirBloqueABytes(), 0);
			}


		} catch (Exception e) {
			
		}
			
	}
	}